package cn.stylefeng.guns.modular.gridsystem.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.core.exception.ServiceException;
import cn.stylefeng.guns.core.factory.PageFactory;
import cn.stylefeng.guns.modular.gridsystem.entity.BizGateway;
import cn.stylefeng.guns.modular.gridsystem.entity.SoundCard;
import cn.stylefeng.guns.modular.gridsystem.enums.SoundCardExceptionEnum;
import cn.stylefeng.guns.modular.gridsystem.mapper.BizGatewayMapper;
import cn.stylefeng.guns.modular.gridsystem.mapper.SoundCardMapper;
import cn.stylefeng.guns.modular.gridsystem.model.param.SoundCardParam;
import cn.stylefeng.guns.modular.gridsystem.model.result.SoundCardResult;
import cn.stylefeng.guns.modular.gridsystem.service.SoundCardService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 声卡业务实现
 *
 * @author zxw 2022/12/15 11:29
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SoundCardServiceImpl extends ServiceImpl<SoundCardMapper, SoundCard> implements SoundCardService {

    private final BizGatewayMapper gatewayMapper;

    @Override
    public Page<SoundCardResult> page(SoundCardParam param) {

        return baseMapper.page(PageFactory.defaultPage(), param);

    }

    @Override
    public List<SoundCardResult> list(SoundCardParam param) {

        if (ObjectUtil.isEmpty(param)) {
            param = new SoundCardParam();
        }

        LambdaQueryWrapper<SoundCard> wrapper = new LambdaQueryWrapper<SoundCard>()
                .like(ObjectUtil.isNotEmpty(param.getCardName()), SoundCard::getCardName, param.getCardName())
                .like(ObjectUtil.isNotEmpty(param.getCode()), SoundCard::getCode, param.getCode())
                .like(ObjectUtil.isNotEmpty(param.getDistinguishCode()), SoundCard::getDistinguishCode, param.getCode());

        return list(wrapper).stream()
                .map(item -> BeanUtil.toBean(item, SoundCardResult.class))
                .collect(Collectors.toList());

    }

    @Override
    public void add(SoundCardParam param) {

        // 1、检查编码是否唯一
        if (count(new LambdaUpdateWrapper<SoundCard>().eq(SoundCard::getCode, param.getCode())) > 0) {
            log.warn("相同编码的声卡已存在，声卡编码为：{}", param.getCode());
            throw new ServiceException(SoundCardExceptionEnum.SAME_CODE_EXIST);
        }

        // 2、检查名称是否唯一
        if (count(new LambdaUpdateWrapper<SoundCard>().eq(SoundCard::getCardName, param.getCardName())) > 0) {
            log.warn("相同名称的声卡已存在，声卡编码为：{}", param.getCode());
            throw new ServiceException(SoundCardExceptionEnum.SAME_NAME_EXIST);
        }

        this.save(BeanUtil.toBean(param, SoundCard.class));

    }

    @Override
    public void edit(SoundCardParam param) {

        SoundCard soundCard = this.queryAndValid(param.getId());

        // 1、检查名称是否唯一
        if (count(new LambdaUpdateWrapper<SoundCard>().eq(SoundCard::getCardName, param.getCardName())
                .ne(SoundCard::getId, soundCard.getId())) > 0) {
            log.warn("相同名称的声卡已存在，声卡编码为：{}", param.getCode());
            throw new ServiceException(SoundCardExceptionEnum.SAME_NAME_EXIST);
        }

        BeanUtil.copyProperties(param, soundCard);

        // 修改数据
        updateById(soundCard);

    }

    @Override
    public void delete(SoundCardParam param) {

        SoundCard soundCard = queryAndValid(param.getId());

        // 1、如果有网关关联到这个声卡，则不允许进行删除操作
        if (gatewayMapper.selectCount(new LambdaUpdateWrapper<BizGateway>().eq(BizGateway::getSoundCardId, soundCard.getId())) > 0) {
            log.warn("有网关应用到这种声卡，不允许删除，声卡主键为：{}", param.getId());
            throw new ServiceException(SoundCardExceptionEnum.GATEWAY_ASSOCIATED_NOT_ALLOWED_DELETE);
        }

        // 2、删除数据
        removeById(queryAndValid(param.getId()));

    }

    /**
     * 私有方法，根据主键查询声卡
     *
     * @param id 要进行查询的声卡主键
     * @return 如果有数据则返回声卡，否则抛出业务异常
     */
    private SoundCard queryAndValid(Long id) {

        SoundCard soundCard = this.getById(id);

        if (ObjectUtil.isEmpty(soundCard)) {
            log.warn("声卡不存在，声卡主键为：{}", id);
            throw new ServiceException(SoundCardExceptionEnum.NOT_EXIST);
        }

        return soundCard;
    }

}
